package com.lmt.ymcc.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.lmt.ymcc.constant.MessageConstant;
import com.lmt.ymcc.domain.*;
import com.lmt.ymcc.dto.*;
import com.lmt.ymcc.feign.SearchFeignClient;
import com.lmt.ymcc.feignclient.MediaFeignClient;
import com.lmt.ymcc.mapper.CourseMapper;
import com.lmt.ymcc.result.JSONResult;
import com.lmt.ymcc.service.*;
import com.lmt.ymcc.utils.AssertUtil;
import com.lmt.ymcc.utils.LoginYmccContext;
import com.lmt.ymcc.vo.CourseInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author AmazingXu
 * @since 2022-08-08
 */
@Service
@Slf4j
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {

    @Autowired
    private ICourseService courseService;

    @Autowired
    private ICourseDetailService courseDetailService;

    @Autowired
    private ICourseMarketService courseMarketService;

    @Autowired
    private ITeacherService teacherService;

    @Autowired
    private ICourseTeacherService courseTeacherService;

    @Autowired
    private ICourseResourceService courseResourceService;

    @Autowired
    private ICourseSummaryService courseSummaryService;

    @Autowired
    private ICourseTypeService courseTypeService;

    @Autowired
    private SearchFeignClient searchFeignClient;

    @Autowired
    private MediaFeignClient mediaFeignClient;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private ICourseChapterService courseChapterService;


    @Override
    @Transactional
    public void save(CourseSaveDto dto) {
        // 把数据接出来
        Course course = dto.getCourse();
        CourseDetail courseDetail = dto.getCourseDetail();
        CourseResource courseResource = dto.getCourseResource();
        CourseMarket courseMarket = dto.getCourseMarket();
        List<Long> teacharIds = dto.getTeacharIds();
        // 存course表
        course.setStatus(Course.COURSE_OFFLINE_STATUS);
        LoginInfoDto loginInfoDto = LoginYmccContext.getLoginInfoDto();
        course.setLoginId(loginInfoDto.getId());
        course.setLoginUserName(loginInfoDto.getUsername());
        List<Teacher> teachers = teacherService.selectBatchIds(teacharIds);
        String teacherNames = teachers.stream().map(t -> t.getName()).collect(Collectors.joining(","));
        course.setTeacherNames(teacherNames);
        courseService.insert(course);
        // 存courseDetail
        courseDetail.setId(course.getId());
        courseDetailService.insert(courseDetail);
        // 存courseResource
        courseResource.setCourseId(course.getId());
        courseResourceService.insert(courseResource);
        // 存courseMarket
        courseMarket.setId(course.getId());
        courseMarketService.insert(courseMarket);
        // 存course和teacher的关联表
        for (Long teacharId : teacharIds) {
            CourseTeacher courseTeacher = new CourseTeacher();
            courseTeacher.setCourseId(course.getId());
            courseTeacher.setTeacherId(teacharId);
            courseTeacherService.insert(courseTeacher);
        }
        // 存summary
        CourseSummary courseSummary = new CourseSummary();
        courseSummary.setId(course.getId());
        courseSummaryService.insert(courseSummary);
        // 修改courseType的值
        CourseType courseType = courseTypeService.selectById(course.getCourseTypeId());
        courseType.setTotalCount(courseType.getTotalCount() + 1);
        courseTypeService.updateById(courseType);
    }

    // 课程发布
    @Override
    @Transactional
    public void onLineCourse(Long id) {
        // 参数校验
        AssertUtil.isNotNull(id, "您没有传递课程id");
        // 通过课程id去查询课程的数据
        Course course = courseService.selectById(id);
        AssertUtil.isNotNull(course, "此课程不存在");
        // 判断课程上下架状态
        boolean offLine = Objects.equals(course.getStatus(), Course.COURSE_OFFLINE_STATUS);
        AssertUtil.isTrue(offLine, "课程已经上架了，请不要重复上架");
        Date date = new Date();
        // 添加上架时间
        course.setOnlineTime(date);
        // 修改为上架状态
        course.setStatus(Course.COURSE_ONLINE_STATUS);
        // 修改上架
        updateById(course);
        // 把课程信息存到es中------------------------------
        CourseDoc courseDoc = new CourseDoc();
        CourseType courseType = courseTypeService.selectById(course.getCourseTypeId());
        CourseMarket courseMarket = courseMarketService.selectById(course.getId());
        CourseSummary courseSummary = courseSummaryService.selectById(course.getId());
        // 把数据拷贝到courseDoc
        BeanUtils.copyProperties(course, courseDoc);
        BeanUtils.copyProperties(courseType, courseDoc);
        BeanUtils.copyProperties(courseMarket, courseDoc);
        BeanUtils.copyProperties(courseSummary, courseDoc);
        courseDoc.setCourseTypeName(courseType.getName());
        courseDoc.setChargeName(courseMarket.getCharge() == 1 ? "免费" : "收费");
        courseDoc.setId(course.getId());
        JSONResult jsonResult = searchFeignClient.saveCourse(courseDoc);
        AssertUtil.isTrue(jsonResult.isSuccess(), "课程发布失败");
        // 推送消息，短信，邮件
        rocketMQTemplate.syncSend(MessageConstant.COURSE_MESSAGE_TOPIC + ":" + MessageConstant.COURSE_MESSAGE_TAG_SMS,
                MessageBuilder.withPayload(SMSDto.builder().title("课程发布啦").content("点击有惊喜").sendTime(new Date()).userId(1L).build())
                        .build());
        log.info("给MQ发送了短信消息");
        rocketMQTemplate.syncSend(MessageConstant.COURSE_MESSAGE_TOPIC + ":" + MessageConstant.COURSE_MESSAGE_TAG_EMAIL,
                MessageBuilder.withPayload(EmailDto.builder().title("课程发布啦").content("点击有惊喜").sendTime(new Date()).userId(1L).
                        email("123@qq.com").build()).build());
        log.info("给MQ发送了邮件消息");
        rocketMQTemplate.syncSend(MessageConstant.COURSE_MESSAGE_TOPIC + ":" + MessageConstant.COURSE_MESSAGE_TAG_STATION,
                MessageBuilder.withPayload(StationDto.builder().title("课程发布啦").content("点击有点惊喜").type("系统消息").sendTime(new Date())
                        .isread(0).userId(1L)).build());
        log.info("给MQ发送了站内消息");
    }

    // 课程下架
    @Override
    public void offLineCourse(Long courseId) {
        // 参数校验
        AssertUtil.isNotNull(courseId, "您没有传递课程id");
        // 通过课程id去查询课程的数据
        Course course = courseService.selectById(courseId);
        AssertUtil.isNotNull(course, "此课程不存在");
        // 判断课程上下架状态
        boolean online = Objects.equals(course.getStatus(), Course.COURSE_ONLINE_STATUS);
        AssertUtil.isTrue(online, "课程已经下架了，请不要重复下架");
        course.setStatus(Course.COURSE_OFFLINE_STATUS);
        // 修改数据库状态
        courseService.updateById(course);
        // 删除es中的数据
        searchFeignClient.delete(course.getId());
    }

    /**
    * @Title: detailData
    * @Description: 课程详情查询
    * @Author: Amazing
    * @Version: 1.0
    * @Date:  2022/8/16 14:33
    * @Parameters: [courseId]
    * @Return com.lmt.ymcc.dto.CourseDetailDto
    */
    @Override
    public CourseDetailDto detailData(Long courseId) {
        // 参数校验
        AssertUtil.isNotNull(courseId, "请选择课程");
        // 查询课程，判断此课程是否是以发布的
        Course course = selectById(courseId);
        AssertUtil.isNotNull(course, "没有此课程");
        AssertUtil.isTrue(Objects.equals(course.getStatus(), Course.COURSE_ONLINE_STATUS), "此课程未上架");
        // 查询汇总
        CourseSummary courseSummary = courseSummaryService.selectById(courseId);
        AssertUtil.isNotNull(courseSummary, "此课程暂时没有汇总");
        // 查询详情
        CourseDetail courseDetail = courseDetailService.selectById(courseId);
        AssertUtil.isNotNull(courseDetail, "此课程暂时没有详情");
        // 查询营销
        CourseMarket courseMarket = courseMarketService.selectById(courseId);
        AssertUtil.isNotNull(courseMarket, "此课程暂时没有售卖信息");
        // 查询章节
        Wrapper<CourseChapter> chapterWrapper = new EntityWrapper<>();
        chapterWrapper.eq("course_id", courseId);
        List<CourseChapter> courseChapters = courseChapterService.selectList(chapterWrapper);
        AssertUtil.isNotNull(courseChapters, "此课程暂时没有章节");
        Map<Long, CourseChapter> chapterMap = courseChapters.stream().collect(Collectors.toMap(CourseChapter::getId, courseChapter -> courseChapter));
        // ----------优化版---------
        JSONResult mediaData = mediaFeignClient.getMediaData(courseId);
        AssertUtil.isTrue(mediaData.isSuccess(), mediaData.getMessage());
        AssertUtil.isTrue(Objects.nonNull(mediaData.getData()), "视频资料查询失败");
        List<MediaFile> mediaFiles1 = JSON.parseArray(mediaData.getData().toString(), MediaFile.class);
        mediaFiles1.stream().forEach(mediaFile ->
            chapterMap.get(mediaFile.getChapterId()).getMediaFiles().add(mediaFile)
        );

        // -----------瓦版--------
        /*List<ChapterVo> chapterVoArrayList = new ArrayList<>();
        for (CourseChapter courseChapter : courseChapters) {
            ChapterVo chapterVo = new ChapterVo();
            List<MediaFile> mediaFiles = (List<MediaFile>) mediaFeignClient.getMediaData(courseChapter.getId()).getData();
            AssertUtil.isNotNull(mediaFiles, "此章节没有视频");
            BeanUtils.copyProperties(courseChapter, chapterVo);
            chapterVo.setMediaFiles(mediaFiles);
            chapterVoArrayList.add(chapterVo);
        }*/
        // 查询教师
        Wrapper<CourseTeacher> courseTeacherWrapper = new EntityWrapper<>();
        courseTeacherWrapper.eq("course_id", courseId);
        List<CourseTeacher> courseTeachers = courseTeacherService.selectList(courseTeacherWrapper);
        AssertUtil.isNotNull(courseTeachers, "此课程暂时没有老师信息");
        List<Teacher> teachers = new ArrayList<>();
        for (CourseTeacher courseTeacher : courseTeachers) {
            Teacher teacher = teacherService.selectById(courseTeacher.getTeacherId());
            AssertUtil.isNotNull(teacher, "此课程暂时没有老师");
            teachers.add(teacher);
        }
        // 把数据设置到返回对象中
        CourseDetailDto courseDetailDto = new CourseDetailDto();
        courseDetailDto.setCourse(course);
        courseDetailDto.setCourseDetail(courseDetail);
        courseDetailDto.setCourseChapters(courseChapters);
        courseDetailDto.setCourseMarket(courseMarket);
        courseDetailDto.setTeachers(teachers);
        courseDetailDto.setCourseSummary(courseSummary);
        return courseDetailDto;
    }

    /**
    * @Title: info
    * @Description: 购买详情页
    * @Author: Amazing
    * @Version: 1.0
    * @Date:  2022/8/16 19:29
    * @Parameters: [courseId]
    * @Return java.util.List<com.lmt.ymcc.dto.CourseDto>
    */
    @Override
    public CourseInfoVo info(String courseIds) {
        // 参数检验
        AssertUtil.isNotNull(courseIds, "请求不合法");
        String[] ids = courseIds.split(",");
        // 查询course
        List<Course> courses = selectBatchIds(Arrays.asList(ids));
        List<CourseDto> courseDtos = new ArrayList<>();
        CourseInfoVo courseInfoVo = new CourseInfoVo();
        for (Course course : courses) {
            AssertUtil.isTrue(Objects.equals(course.getStatus(), Course.COURSE_ONLINE_STATUS), "此课程未上架");
            // 查询courseMarket
            CourseMarket courseMarket = courseMarketService.selectById(course.getId());
            AssertUtil.isNotNull(courseMarket, "课程没有售卖信息");
            courseInfoVo.getTotalAmount().add(courseMarket.getPrice());
            courseDtos.add(new CourseDto(course, courseMarket));
            courseInfoVo.setTotalAmount(courseInfoVo.getTotalAmount().add(courseMarket.getPrice()));
        }
        courseInfoVo.setCourseInfos(courseDtos);
        // 计算价格
        return courseInfoVo;
    }
}
